﻿using System;
using System.Data.Common;
using System.Web;
using System.Web.Mvc;
using QDT.Common;
using QDT.Common.Plugins;
using QDT.Common.Plugins.Email;
using QDT.P2B.Domain.Config;
using QDT.Services;
using QDT.Web.Code;
using QDT.Web.Code.Attributes;
using QDT.Web.Models;
using QDT.Services.Members;
using QDT.Core.Members;
using QDT.MVC;
using System.Linq;
using QDT.P2B.Domain.Messages;
using System.Web.Hosting;

namespace QDT.Web.Controllers
{
    public class AccountController : BaseController
    {

        private readonly IUserService _userService;
        private readonly IFormsAuthenticationService _authenticationService;

        public AccountController(IUserService userService, IFormsAuthenticationService authenticationService)
        {
            Check.Argument.IsNotNull(userService, "userService");
            Check.Argument.IsNotNull(authenticationService, "authenticationService");

            _userService = userService;
            _authenticationService = authenticationService;
        }

        [HttpsRequire]
        public ActionResult Register(int pid = 0)
        {
            ViewBag.Pid = pid;
            return View();
        }

        /// <summary>
        /// 线下注册
        /// </summary>
        public ActionResult RegisterPlus()
        {
            return View();
        }
        /// <summary>
        /// 推广注册
        /// </summary>
        /// <returns></returns>
        public ActionResult RegisterTG()
        {
            return View();
        }

        public ActionResult RegSuccess()
        {
            return View(QDTContext.Current.User);
        }

        public ActionResult Ajax_IsExist(string name)
        {
            if (string.IsNullOrWhiteSpace(name))
            {
                return Json(new
                {
                    Status = 1,
                    Info = "用户名为空"
                });
            }
            if (DbProvider.D<User>().Any(x => x.UserName.Equals(name)))
            {
                return Json(new
                {
                    Status = 1,
                    Info = "已存在"
                });
            }
            return Json(new
            {
                Status = 0,
                Info = "可用"
            });
        }

        public ActionResult Phone_IsExist(string phone)
        {
            if (string.IsNullOrWhiteSpace(phone))
            {
                return Json(new
                {
                    Status = 0,
                    Info = "手机号为空"
                });
            }
            if (DbProvider.D<User>().Any(x => x.Mobile.Equals(phone) && x.MobilePassed && x.GroupID.Equals(3) && x.IsEffect && !x.IsDelete))
            {
                return Json(new
                {
                    Status = 1,
                    Info = "已存在"
                });
            }
            return Json(new
            {
                Status = 0,
                Info = "可用"
            });
        }

        public ActionResult PostRegisterTG(UserRegisterModel model)
        {
            //if (!ModelState.IsValid) return Error();
            var validate = Request.Cookies["valicode"];
            if (validate == null) return Error("验证码错误！");
            if (model.ValidateCode.Hash().Hash() != validate.Value) return Error("验证码错误！");

            try
            {
                var username = new HttpCookie("14c4b06b824ec593239362517f538b29") { Value = model.UserName.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var password = new HttpCookie("5f4dcc3b5aa765d61d8327deb882cf99") { Value = model.Password.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var mobile = new HttpCookie("532c28d5412dd75bf975fb951c740a30") { Value = model.Mobile.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var pmobile = new HttpCookie("d7e95e009e3eafe8af9a558faf44626c") { Value = string.IsNullOrWhiteSpace(model.PName) ? "" : model.PName.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };

                Response.AppendCookie(username);
                Response.AppendCookie(password);
                Response.AppendCookie(mobile);
                Response.AppendCookie(pmobile);

                var vCode = IoC.Resolve<ValidateImage>();
                var code = vCode.CreateValidateCode(4);
                var valicode = new HttpCookie("d50b43c7e7d8ea2faaa2af7cee7416ce") { Value = code.Hash().Hash(), Expires = DateTime.Now.AddMinutes(30) };

                Response.AppendCookie(valicode);

                var msg = new MsgQueueFactory().CreateValidatorMsg(model.Mobile, code);
                DbProvider.Add(msg);
                DbProvider.SaveChanges();

                IoC.Resolve<ValicodeController>().QuickSendSMS(msg);

                return RedirectToAction("RegisterValidata");
            }
            catch (UserCreateException userException)
            {
                switch (userException.StatusCode)
                {
                    case UserCreateException.DuplicateUserName:
                        return Json(new { Status = 1, Info = "用户名已经存在" });
                    default:
                        throw userException.InnerException;
                }
            }
        }

        [HttpPost]
        [ActionName("Register")]
        [ValidateAntiForgeryToken]
        public ActionResult PostRegister(UserRegisterModel model)
        {
            if (!ModelState.IsValid) return Error();
            var validate = Request.Cookies["valicode"];
            if (validate == null) return Error("验证码错误！");
            if (model.ValidateCode.Hash().Hash() != validate.Value) return Error("验证码错误！");

            try
            {
                var username = new HttpCookie("14c4b06b824ec593239362517f538b29") { Value = model.UserName.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var password = new HttpCookie("5f4dcc3b5aa765d61d8327deb882cf99") { Value = model.Password.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var mobile = new HttpCookie("532c28d5412dd75bf975fb951c740a30") { Value = model.Mobile.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };
                var pmobile = new HttpCookie("d7e95e009e3eafe8af9a558faf44626c") { Value = string.IsNullOrWhiteSpace(model.PName) ? "" : model.PName.ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(30) };

                Response.AppendCookie(username);
                Response.AppendCookie(password);
                Response.AppendCookie(mobile);
                Response.AppendCookie(pmobile);

                var vCode = IoC.Resolve<ValidateImage>();
                var code = vCode.CreateValidateCode(4);
                var valicode = new HttpCookie("d50b43c7e7d8ea2faaa2af7cee7416ce") { Value = code.Hash().Hash(), Expires = DateTime.Now.AddMinutes(30) };

                Response.AppendCookie(valicode);

                var msg = new MsgQueueFactory().CreateValidatorMsg(model.Mobile, code);
                DbProvider.Add(msg);
                DbProvider.SaveChanges();

                IoC.Resolve<ValicodeController>().QuickSendSMS(msg);
                return RedirectToAction("RegisterValidata");
            }
            catch (UserCreateException userException)
            {
                switch (userException.StatusCode)
                {
                    case UserCreateException.DuplicateUserName:
                        return Json(new { Status = 1, Info = "用户名已经存在" });
                    default:
                        throw userException.InnerException;
                }
            }
        }

        public ActionResult RegisterValidata()
        {
            var usernameCk = Request.Cookies["14c4b06b824ec593239362517f538b29"];
            return usernameCk == null ? Error("请先注册") : View();
        }

        /// <summary>
        /// 线下注册
        /// </summary>
        [HttpPost]
        public ActionResult PostPhoneValidata(string validateCode)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(validateCode)) return Error("请输入正确的验证码");

                var validate = Request.Cookies["d50b43c7e7d8ea2faaa2af7cee7416ce"];

                if (validate == null) return Error("验证码错误！");
                if (validateCode.Hash().Hash() != validate.Value) return Error("验证码错误！" );

                var mobileCk = Request.Cookies["532c28d5412dd75bf975fb951c740a30"];
                var usernameCk = Request.Cookies["14c4b06b824ec593239362517f538b29"];
                var passwordCk = Request.Cookies["5f4dcc3b5aa765d61d8327deb882cf99"];
                var pmobileCk = Request.Cookies["d7e95e009e3eafe8af9a558faf44626c"];
                if (mobileCk == null || usernameCk == null || passwordCk == null || pmobileCk == null) return Error("验证码错误！");

                var pUser = _userService.GetUserByMobile(string.IsNullOrWhiteSpace(pmobileCk.Value) ? "" : pmobileCk.Value.ToDesDecrypt(Des.QDT_Key));
                var pid = pUser == null ? 0 : pUser.ID;

                var mobile = mobileCk.Value.ToDesDecrypt(Des.QDT_Key);
                var username = usernameCk.Value.ToDesDecrypt(Des.QDT_Key);
                var password = passwordCk.Value.ToDesDecrypt(Des.QDT_Key);

                var user = _userService.CreateUser(username, password, mobile, pid);
                SaveLoginInfo(user);

                DbProvider.Refresh(user.UserAccount);
//                user.UserAccount.ExpMoney += 10000;
//                user.UserAccount.Money += 5;

//                var log = new UserTransLog(user.ID, UserTransLog.TradeType.Other, 5, user.UserAccount.Money)
//                {
//                    Info = "注册就送体验金（10000）",
//                };
//
//                if (pid != 0)
//                {
//                    var puser = DbProvider.GetByID<User>(pid);
//                    DbProvider.Refresh(puser.UserAccount);
//                    puser.UserAccount.ExpMoney += 10000;
//                    puser.UserAccount.Money += 5;
//                    var plog = new UserTransLog(pid, UserTransLog.TradeType.Other, 5, puser.UserAccount.Money)
//                    {
//                        Info = "推荐用户送现金红包（5）&体验金（10000）",
//                    };
//                    DbProvider.Add(plog);
//                }
//                DbProvider.Add(log);
                DbProvider.SaveChanges();

                _authenticationService.SignIn(user.UserName, false);

                return RedirectToAction("RegSuccess");
            }
            catch (Exception)
            {
                throw new Exception();
            }

        }

        /// <summary>
        /// 线下注册
        /// </summary>
        [HttpPost]
        public ActionResult PostRegPlus(UserRegPlusModel model)
        {
            if (!ModelState.IsValid) return Error();

            var isHas = DbProvider.D<User>().Any(x => x.IDCard.Equals(model.IdCard) && x.IDCardPassed && x.GroupID == 1);

            if (isHas) return Error("身份证号码已存在");

            try
            {
                DbProvider.IsNotSubmit = true;
                var user = _userService.CreateOfflineUser(model.UserName, model.Password, model.IdCard, model.RealName, model.Phone);
                user.DepartmentBelong = model.Department;
                user.SalesmanBelong = model.Salesman;
                DbProvider.IsNotSubmit = false;
                DbProvider.SaveChanges();
                ViewData["Jump"] = Url.Action("Index", "Home");

                //跳转到首页，后期可以改成跳转到用户中心
                return Success("注册成功");
            }
            catch (UserCreateException userException)
            {
                switch (userException.StatusCode)
                {
                    case UserCreateException.DuplicateUserName:
                        return Error("用户名已经存在.");
                    case UserCreateException.DuplicateEmail:
                        return Error("电子邮件已经存在.");
                    case UserCreateException.InvaildEmail:
                        return Error("无效的电子邮件地址.");
                    default:
                        throw userException.InnerException;
                }
            }
        }

        [HttpsRequire]
        public ActionResult LogIn()
        {
            if (QDTContext.Current.IsAuthenticated)
            {
                return Redirect("~/");
            }
            return View(new UserLoginModel() { ReturnUrl = Request["ReturnUrl"] });
        }

        [HttpPost]
        [ActionName("LogIn")]
        [ValidateAntiForgeryToken]
        public ActionResult PostLogIn(UserLoginModel model)
        {
            if (!ModelState.IsValid) return Error();
            User user;

            var vaild = _userService.ValidateUser(model.UserName, model.Password, out user);
            if (!vaild)
            {
                ModelState.AddModelError("", "账号或密码错误!");
                return View(model);
            }

            _authenticationService.SignIn(user.UserName, false);

            SaveLoginInfo(user);

            var returnUrl = Url.IsLocalUrl(model.ReturnUrl) ? model.ReturnUrl : Url.Content("~/");
            return Redirect(returnUrl);
        }

        public ActionResult LogOut()
        {
            _authenticationService.SignOut();
            return Redirect(Url.Content("~/"));
        }

        #region 忘记密码

        public ActionResult ForgetPassword()
        {
            return View();
        }

        [HttpPost]
        public ActionResult PostForgetPassword(string validate, string userName)
        {
            var cookie = Request.Cookies["valicode"];

            if (cookie == null)
            {
                return Error("验证码不能为空！");
            }

            var cookieValue = cookie.Value;

            if (validate.Hash().Hash() != cookieValue)
            {
                ModelState.AddModelError("", "验证码错误!");
                return RedirectToAction("ForgetPassword");
            }
            var user = _userService.GetUserByAll(userName);
            if (user == null) return Error("不存在此用户！");

            var userCookie = new HttpCookie("qdt_account") { Value = user.ID.ToString().ToDesEncrypt(Des.QDT_Key), Expires = DateTime.Now.AddMinutes(300) };

            Response.AppendCookie(userCookie);

            return RedirectToAction("FindPasswordByPhone");

        }

        public ActionResult FindPasswordByEmail()
        {
            var qdt_account = Request.Cookies["qdt_account"];
            if (qdt_account == null) return NotFound();
            return View();
        }

        public ActionResult SendPasswordByEmail(string email)
        {

            if (!email.IsEmail()) return Error("请输入正确的电子邮件");

            var qdt_account = Request.Cookies["qdt_account"];
            if (qdt_account == null) return Error("此页面已经过期");

            var Pid = Convert.ToInt32(qdt_account.Value.ToDesDecrypt(Des.QDT_Key));

            var user = DbProvider.GetByID<User>(Pid);
            if (!user.EmailPassed || email != user.Email)
            {
                return Error("电子邮件与绑定邮箱地址不匹配！");
            }

            var Ptime = DateTime.Now.Ticks;
            var Psign = email + Des.QDT_Key + Ptime.ToString();
            var resetUrl = MakeActiveUrl(Url.Action("ResetPasswordByEmail", "Account", new { email = email, time = Ptime, sign = Psign.Hash().Hash() }));
            var content = PrepareMailBodyWith("ForgetPwd", "Email", email, "ResetUrl", resetUrl);
            var msg = new MsgQueueFactory().CreateValidatorMsg(email, "众禧贷找回密码", content);
            msg.IsSend = true;

            DbProvider.Add(msg);
            DbProvider.SaveChanges();

            SendMailMessage(msg);

            return View("EmailFindpasswordSuccess", user);
        }

        public ActionResult ResetPasswordByEmail(string email, long time, string sign)
        {
            string str = email + Des.QDT_Key + time.ToString();
            if (str.Hash().Hash() != sign)
            {
                return Error("验证未通过！无效的链接！");
            }
            if ((DateTime.Now - new DateTime(time)).TotalHours > 0.5)
            {
                return Error("时间超过半个小时，验证失效，请从新发送邮件进行验证！");
            }

            var des = email.ToDesEncrypt(Des.QDT_Key);

            ViewData["ValidCode"] = des;

            return View("ResetPassword");
        }

        [HttpPost]
        public ActionResult ResetPassword(string validate, string password, string confirmPassword)
        {
            if (password != confirmPassword)
            {
                return Error("密码不一致！");
            }

            var user = _userService.GetUserByAll(validate.ToDesDecrypt(Des.QDT_Key));

            user.ChangePassword(password);
            _userService.UpdateUser(user);

            return View("FindPasswordSuccess", user);
        }

        public ActionResult FindPasswordByPhone()
        {
            var qdt_account = Request.Cookies["qdt_account"];
            if (qdt_account == null) return NotFound();
            return View();
        }

        [HttpPost]
        public ActionResult RestPasswordByPhone(string mobile, string validateCode)
        {
            var phone = Request.Cookies["mobile"];
            var valicode = Request.Cookies["valicode"];

            if (valicode == null || phone == null)
            {
                return Error("验证码不正确！");
            }

            var valicodeValue = valicode.Value;
            var phoneValue = phone.Value;

            if (mobile.Hash().Hash() != phoneValue)
            {
                ModelState.AddModelError("", "手机号码不正确！");
                return Error("手机号码不正确！");
            }

            if (validateCode.Hash().Hash() != valicodeValue)
            {
                ModelState.AddModelError("", "验证码错误!");
                return Error("验证码不正确！");
            }

            var des = mobile.ToDesEncrypt(Des.QDT_Key);

            ViewData["ValidCode"] = des;

            return View("ResetPassword");
        }


        private string PrepareMailBodyWith(string templateName, params string[] pairs)
        {
            string body = GetMailBodyOfTemplate(templateName);

            for (var i = 0; i < pairs.Length; i += 2)
            {
                body = body.Replace("<%={0}%>".FormatWith(pairs[i]), pairs[i + 1]);
            }

            body = body.Replace("<%=siteTitle%>", "众禧贷").Replace("<%=rootUrl%>", "");

            return body;
        }

        private string GetMailBodyOfTemplate(string templateName)
        {
            string body = string.Empty;
            if (string.IsNullOrEmpty(body))
            {
                body = ReadFileFrom(templateName);
            }
            return body;
        }

        private string ReadFileFrom(string templateName)
        {
            string templateDirectory = HostingEnvironment.IsHosted
            ? HostingEnvironment.MapPath("~/Content/EmailTemp") ?? ""
            : System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "EmailTemp");

            string filePath = string.Concat(System.IO.Path.Combine(templateDirectory, templateName), ".txt");

            string body = System.IO.File.ReadAllText(filePath);

            return body;
        }

        private string MakeActiveUrl(string action)
        {
            Uri requestUrl = Url.RequestContext.HttpContext.Request.Url;
            return "{0}://{1}{2}".FormatWith(requestUrl.Scheme, requestUrl.Authority, action);
        }

        #endregion

        /// <summary>
        /// 保存登录信息
        /// </summary>
        /// <param name="user"></param>
        private void SaveLoginInfo(User user)
        {
            user.LoginTime = DateTime.Now;
            user.LoginIP = Utility.GetIP();
            _userService.UpdateUser(user);
        }

        private void SendMailMessage(MsgQueue msg)
        {
            var config = SettingManager.Get<EmailConfig>();

            IEmailSender sender = new EmailSender(config.SmtpServer, config.SmtpPort, config.Name, config.SmtpUserName, config.SmtpPassword, config.IsSSL);

            sender.SendMail(msg.Dest, msg.Title, msg.Content, msg.ID, (o, e) =>
            {
                var m = DbProvider.GetByID<MsgQueue>(e.UserState);
                if (e.Error != null)
                {
                    m.IsSuccess = false;
                    m.Result = e.Error.Message;
                }
                else
                {
                    m.IsSuccess = true;
                }
                DbProvider.SaveChanges();
            });
        }

        public ActionResult PostBindEmail(int id, string email, long time, string sign)
        {
            var str = email + Des.QDT_Key + time;

            if (str.Hash().Hash() != sign) return Error("验证未通过！无效的链接！");

            if ((DateTime.Now - new DateTime(time)).TotalHours > 0.5) return Error("时间超过半个小时，验证失效，请从新发送邮件进行验证！");

            var user = _userService.GetUserByEmail(email);
            if (user != null) return Error("该邮箱已经被使用！");

            user = _userService.GetUserByID(id);
            if (user == null) return Error("用户不存在！无效的链接");

            user.BindEmail(email);
            _userService.UpdateUser(user);

            return Success("绑定邮箱成功！");
        }

    }

}